﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DigitalImage.neuronska;
using OcrTemplate.Utilities;
using DigitalImage.util;
using AGisCore;
using AGisCore.Entity;
using DigitalImage.softLib;
using DigitalImage.softLib.stages;
using DigitalImage.softLib.stages._2ColorToBinary;
using DigitalImage.softLib.stages._3BinaryTransformations;
using DigitalImage.softLib.stages._5NeuralNetwork;
using DigitalImage.softLib.stages._6DictionaryCheck;
using DigitalImage.softLib.stages._4RegionLabelling;
using System.IO;

namespace DigitalImage
{
    public partial class btnCreateSimLib : Form
    {
        private ImageEditor.util.SCKolokvijum2013 kolokvijum = new ImageEditor.util.SCKolokvijum2013("E13528", "Vojislav", "Djukic", "LK0BG",
                ImageEditor.util.ZaOcenu.Osam, @"..\..\..\alfabet.txt", @"..\..\..\CrtaniHobbit.txt");

        BackPropagation bp = null;
        private CSoftLib softPipe=null;
        public btnCreateSimLib()
        {
            InitializeComponent();
        }

        Bitmap prevImage = null;
        private void btnLoadBitmap_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                String imageFileName = ofd.FileName;
                Bitmap bmp = new Bitmap(imageFileName);
                prevImage = imageEditorDisplay1.mapa.bmp;

                imageEditorDisplay1.mapa.bmp = bmp;
                imageEditorDisplay1.FitImage();
                imageEditorDisplay1.Refresh();

                Properties.Settings.Default.imagePath = imageFileName;
                Properties.Settings.Default.Save();

            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            SaveFileDialog ofd = new SaveFileDialog();
            string fileName = DateTime.Now.ToString("yyyy-MM-dd hh-mm-ss") + ".bmp";
            ofd.FileName = fileName;
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                String imageFileName = ofd.FileName;
                imageEditorDisplay1.mapa.bmp.Save(imageFileName);
            }
        }

        private void btnReload_Click(object sender, EventArgs e)
        {
            String str = Properties.Settings.Default.imagePath;
            if (!String.IsNullOrEmpty(str))
            {
                Bitmap bmp = new Bitmap(str);

                imageEditorDisplay1.mapa.bmp = bmp;
                imageEditorDisplay1.FitImage();
                imageEditorDisplay1.Refresh();
            }

        }

        private void btnBinaryTiles_Click(object sender, EventArgs e)
        {
            Bitmap bmp = imageEditorDisplay1.mapa.bmp;
            byte[,] slika = ImageUtil.bitmapToByteMatrix(bmp);
            byte[,] bSlika = ImageUtil.matrixToBinaryTiles(slika, 15, 15);
            Bitmap temp = ImageUtil.matrixToBitmap(bSlika);
            imageEditorDisplay1.mapa.bmp = temp;
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            String str = Properties.Settings.Default.imagePath;
            if (!String.IsNullOrEmpty(str))
            {
                Bitmap bmp = new Bitmap(str);

                imageEditorDisplay1.mapa.bmp = bmp;
                imageEditorDisplay1.FitImage();
                imageEditorDisplay1.Refresh();
            }
            //btnOcenjivanje_Click(null, null);
        }

        private void btnHistogram_Click(object sender, EventArgs e)
        {
            Bitmap bmp = imageEditorDisplay1.mapa.bmp;
            byte[,] slika = ImageUtil.bitmapToByteMatrix(bmp);
            List<PointF> points = ImageUtil.histogram(slika);
            Function f1 = new Function(Color.Red, points, Function.VBAR);
            List<Function> ff = new List<Function>();
            ff.Add(f1);
            FrmChart chart = new FrmChart(ff);
            chart.Show();
        }

        private void btnGreyScale_Click(object sender, EventArgs e)
        {
            Bitmap bmp = imageEditorDisplay1.mapa.bmp;

            byte[,] slika = ImageUtil.bitmapToByteMatrix(bmp);

            imageEditorDisplay1.mapa.bmp = ImageUtil.matrixToBitmap(slika);
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
        }

        private void btnRegionLabeling_Click(object sender, EventArgs e)
        {
            Bitmap bmp = imageEditorDisplay1.mapa.bmp;

            byte[,] slika = ImageUtil.bitmapToByteMatrix(bmp);
            List<RasterRegion> regions = ImageUtil.regionLabeling(slika);
            foreach (RasterRegion reg in regions)
            {
                reg.odrediMomente();
            }
            double minEcc = double.MaxValue;
            double maxEcc = double.MinValue;
            foreach (RasterRegion reg in regions)
            {
                minEcc = Math.Min(reg.eccentricity, minEcc);
                maxEcc = Math.Max(reg.eccentricity, maxEcc);
            }

            List<PointF> points = new List<PointF>();
            int[] exccs = new int[101];
            double a = 100 / (maxEcc - minEcc);
            double b = -a * minEcc;
            foreach (RasterRegion reg in regions)
            {
                double ecc = reg.eccentricity;
                double f = a * ecc + b;
                exccs[(int)f]++;

            }
            for (int i = 0; i < exccs.Length; i++)
            {
                float x = (float)((i - b) / a);
                points.Add(new PointF(100 * x, exccs[i]));
            }
            Function f1 = new Function(Color.Red, points, Function.VBAR);
            //functionPlot1.funkcije.Add(f1);
            //functionPlot1.Reset();
            //functionPlot1.FitToScreen();

            List<Function> ff = new List<Function>();
            ff.Add(f1);
            //FrmChart chart = new FrmChart(ff);
            //chart.Show();

            foreach (RasterRegion reg in regions)
            {
                double angle = 180 * reg.theta / Math.PI;
                byte color = 250; // belo


                if (reg.majorAxisLength > 5000 && reg.majorAxisLength < 500000 &&
                      reg.eccentricity < 1 && angle > 0 && angle <= 180 && (reg.majorAxisLength/reg.minorAxisLength) > 30)
                {
                    color = 30; // skoro crno
                }

                foreach (Point pp in reg.points)
                {
                    slika[pp.Y, pp.X] = color;
                }

            }
            imageEditorDisplay1.mapa.bmp = ImageUtil.matrixToBitmap(slika);
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
        }

        private void btnSobel_Click(object sender, EventArgs e)
        {
            Bitmap bmp = imageEditorDisplay1.mapa.bmp;

            byte[,] slika = ImageUtil.bitmapToByteMatrix(bmp);
            byte[,] nslika = ImageUtil.iviceSobel(slika);
            imageEditorDisplay1.mapa.bmp = ImageUtil.matrixToBitmap(nslika);
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
        }

        private void btnInvert_Click(object sender, EventArgs e)
        {
            Bitmap bmp = imageEditorDisplay1.mapa.bmp;

            byte[,] slika = ImageUtil.bitmapToByteMatrix(bmp);
            byte[,] nslika = ImageUtil.invert(slika);
            imageEditorDisplay1.mapa.bmp = ImageUtil.matrixToBitmap(nslika);
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
        }

        private void btnDilation_Click(object sender, EventArgs e)
        {
            Bitmap bmp = imageEditorDisplay1.mapa.bmp;
            byte[,] slika = ImageUtil.bitmapToByteMatrix(bmp);
            //byte[,] nslika = iviceSobel(slika);
            //byte[,] islika = invert(nslika);
            //byte pola = kMeansTreshold(islika);
            //byte[,] bSlika = ImageUtil.matrixToBinary(islika, (byte)pola);

            byte[,] dSlika = ImageUtil.dilation(slika);

            imageEditorDisplay1.mapa.bmp = ImageUtil.matrixToBitmap(dSlika);
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
        }

        private void btnErosion_Click(object sender, EventArgs e)
        {
            Bitmap bmp = imageEditorDisplay1.mapa.bmp;
            byte[,] slika = ImageUtil.bitmapToByteMatrix(bmp);
            //byte[,] nslika = iviceSobel(slika);
            //byte[,] islika = invert(nslika);
            //byte pola = kMeansTreshold(islika);
            //byte[,] bSlika = ImageUtil.matrixToBinary(islika, (byte)pola);

            //byte[,] dSlika = ImageUtil.dilation(bSlika);
            byte[,] eSlika = ImageUtil.erosion(slika);

            imageEditorDisplay1.mapa.bmp = ImageUtil.matrixToBitmap(eSlika);
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
        }

        private void btnDiff_Click(object sender, EventArgs e)
        {
            if (prevImage != null)
            {
                Bitmap bmp = imageEditorDisplay1.mapa.bmp;

                byte[,] slika = ImageUtil.bitmapToByteMatrix(bmp);
                byte[,] slikaB = ImageUtil.bitmapToByteMatrix(prevImage);
                byte[,] nslika = ImageUtil.diff(slika, slikaB);
                imageEditorDisplay1.mapa.bmp = ImageUtil.matrixToBitmap(nslika);
                imageEditorDisplay1.FitImage();
                imageEditorDisplay1.Refresh();
            }
        }

        private void btnThreshold_Click(object sender, EventArgs e)
        {
            FrmThreshold threshold = new FrmThreshold(this);
            threshold.Show();
        }

        private void btnCopy_Click(object sender, EventArgs e)
        {
            imageEditorDisplay1.CopyToClipboard();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Bitmap bmp = imageEditorDisplay1.mapa.bmp;
            byte[,] slika = ImageUtil.bitmapToByteMatrix(bmp);
            byte[,] dilatacijaSlika = ImageUtil.dilation(slika);

            byte[,] ivicaSlika = ImageUtil.diff(dilatacijaSlika, slika);

            imageEditorDisplay1.mapa.bmp = ImageUtil.matrixToBitmap(ivicaSlika);
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Bitmap bmp = imageEditorDisplay1.mapa.bmp;
            byte[,] slika = ImageUtil.bitmapToByteMatrix(bmp);

            byte[,] blurSlika = ImageUtil.blur(slika);

            imageEditorDisplay1.mapa.bmp = ImageUtil.matrixToBitmap(blurSlika);
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            Bitmap bmp = imageEditorDisplay1.mapa.bmp;
            byte[,] slika = ImageUtil.bitmapToByteMatrix(bmp);
            byte[,] blurovanaSlika = ImageUtil.blur(slika);

            for (int i = 0; i < 10; i++)
                blurovanaSlika = ImageUtil.blur(blurovanaSlika);

            byte[,] detaljiSlika = ImageUtil.diff(slika, blurovanaSlika);

            imageEditorDisplay1.mapa.bmp = ImageUtil.matrixToBitmap(detaljiSlika);
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
        }

        private void btnOtsu_Click(object sender, EventArgs e)
        {
            Bitmap bmp = imageEditorDisplay1.mapa.bmp;
            byte[,] slika = ImageUtil.bitmapToByteMatrix(bmp);
            int threshold = ImageUtil.otsu(slika);
            slika = ImageUtil.matrixToBinary(slika, (byte)threshold);

            imageEditorDisplay1.mapa.bmp = ImageUtil.matrixToBitmap(slika);
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
        }

        private void btnColorSegmentation_Click(object sender, EventArgs e)
        {
            FrmColorSegmentation frmColorSegmentation = new FrmColorSegmentation(this);
            frmColorSegmentation.Show();
        }

        private double[] pripremiSlikuZaVNM(byte[,] slika)
        {
            // na osnovu slike koja je dimenzija 64x64 napraviti vektor od 64 elementa
            double[] retVal = new double[64];

            for (int i = 0; i < slika.GetLength(0); i++)
            {
                for (int j = 0; j < slika.GetLength(1); j++)
                {
                    if (slika[i, j] < 255)
                    {
                        int ii = i / 8;
                        int jj = j / 8;

                        retVal[ii * 8 + jj]++;
                    }
                }
            }

            // skaliranje sa [0,64] na [-1,1]
            for (int i = 0; i < retVal.Length; i++)
            {
                retVal[i] = retVal[i] / 32 - 1;
            }
            return retVal;
        }

        List<RasterRegion> kandidati = null;
        Dictionary<String, int> alfabet = new Dictionary<string, int>();
        Dictionary<int, String> alfabetInv = new Dictionary<int, string>();

        private void btnObeleziKandidate_Click(object sender, EventArgs e)
        {
            Bitmap bmp = imageEditorDisplay1.mapa.bmp;
            byte[,] oSlika = ImageUtil.bitmapToByteMatrix(bmp);
            byte[,] slika = ImageUtil.matrixToBinary(oSlika, 200);

            int w = slika.GetLength(1);
            int h = slika.GetLength(0);

            kandidati = ImageUtil.regionLabeling(slika);
            foreach (RasterRegion reg in kandidati)
            {
                reg.odrediMomente();
            }

            // ovde spojiti tacke i kukice njima odgovarajucim slovima
            kandidati = SpojiTackeIKukice(kandidati);

            foreach (RasterRegion reg in kandidati)
            {
                reg.odrediMomente();
            }

            // ovde sloziti slova u redove i kolone
            String[] linije = tbTrenningSet.Text.Replace("\r", "").Split('\n');
            String slova = tbTrenningSet.Text.Replace("\n", "").Replace("\r", "");
            int rr = 0;
            List<RasterRegion> slozeniKandidati = new List<RasterRegion>();
            for (int i = 0; i < linije.Length; i++)
            {
                String linija = linije[i];
                int N = linija.Length;
                List<RasterRegion> red = new List<RasterRegion>();
                for (int j = 0; j < N; j++)
                {
                    red.Add(kandidati[rr]);
                    rr++;
                }
                red.Sort(new DigitalImage.util.RasterRegion.RComparer());
                foreach (RasterRegion regS in red)
                    slozeniKandidati.Add(regS);
            }
            kandidati = slozeniKandidati;

            int regId = 0;
            int redBr = 0;
            foreach (RasterRegion reg in kandidati)
            {
                List<Tacka> tacke = new List<Tacka>();
                tacke.Add(new Tacka(reg.minX - 1, reg.minY - 1));
                tacke.Add(new Tacka(reg.maxX + 1, reg.minY - 1));
                tacke.Add(new Tacka(reg.maxX + 1, reg.maxY + 1));
                tacke.Add(new Tacka(reg.minX - 1, reg.maxY + 1));
                Poligon rec = new Poligon(tacke, Color.FromArgb(10, Color.Green));
                imageEditorDisplay1.selectedIndexer.add(rec);
                reg.Tag = "" + slova[regId];
                if (!alfabet.ContainsKey(reg.Tag))
                {
                    alfabet.Add(reg.Tag, redBr);
                    alfabetInv.Add(redBr, reg.Tag);
                    redBr++;
                }

                Labela lbl = new Labela(reg.minX - 1, reg.minY - 1);
                lbl.boja = Color.Red;
                lbl.labela = reg.Tag;
                imageEditorDisplay1.selectedIndexer.add(lbl);
                regId++;
            }
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
        }

        double[, ,] obucavajuciSkup = null;
        int brojUzoraka = 0;
        private void btnTrainingSet_Click(object sender, EventArgs e)
        {
            brojUzoraka = kandidati.Count;
            obucavajuciSkup = new double[brojUzoraka, 2, 64];
            Size size = new Size(64, 64);
            for (int uzorak = 0; uzorak < brojUzoraka; uzorak++)
            {
                RasterRegion reg = kandidati[uzorak];

                byte[,] regSlika = reg.odrediNSliku(); // ispravi region da stoji uspravno
                byte[,] nSlika = ImageUtil.resizeImage(regSlika, size); // resize na 64x64
                double[] ulaz = pripremiSlikuZaVNM(nSlika); // kreiraj vektor od 64 elementa na osnovu 64x64 slike
                int index = alfabet[reg.Tag]; // nadji koji je index (u izlaznom sloju) obelezeni region

                // formiranje obucavajuceg skupa
                // - na ulaze neuronske mreze dovodi se kreirani vektor od 64 elementa
                for (int k = 0; k < ulaz.Length; k++)
                {
                    obucavajuciSkup[uzorak, 0, k] = ulaz[k];
                }

                // - na izlaz koji odgovara indeksu postaviti 1, na ostale 0
                for (int ii = 0; ii < alfabet.Count; ii++)
                {
                    if (ii == index)
                        obucavajuciSkup[uzorak, 1, ii] = 1;
                    else
                        obucavajuciSkup[uzorak, 1, ii] = 0;
                }
            }

            MessageBox.Show("Obucavajuci skup formiran! ");
        }

        private void btnTraining_Click(object sender, EventArgs e)
        {
            if (bp != null)
            {
                brojUzoraka = obucavajuciSkup.GetLength(0) + bp.obucavajuciSkup.GetLength(0);
                double[, ,] novi = new double[brojUzoraka, 2, 64];
                for (int i = 0; i < brojUzoraka; i++)
                {
                    if (i < obucavajuciSkup.GetLength(0))
                    {
                        for (int j = 0; j < obucavajuciSkup.GetLength(1); j++)
                        {
                            for (int k = 0; k < obucavajuciSkup.GetLength(2); k++)
                            {
                                novi[i, j, k] = obucavajuciSkup[i, j, k];
                            }
                        }
                    }
                    else
                    {
                        for (int j = 0; j < bp.obucavajuciSkup.GetLength(1); j++)
                        {
                            for (int k = 0; k < bp.obucavajuciSkup.GetLength(2); k++)
                            {
                                novi[i, j, k] = bp.obucavajuciSkup[i - obucavajuciSkup.GetLength(0), j, k];
                            }
                        }
                    }
                }

                obucavajuciSkup = novi;
            }
            bp = new BackPropagation(obucavajuciSkup);
            bp.obuci();

            Function f1 = new Function(Color.Red, bp.greske, Function.VBAR);
            List<Function> ff = new List<Function>();
            ff.Add(f1);
            FrmChart chart = new FrmChart(ff);
            chart.Show();
        }

        private List<RasterRegion> SpojiTackeIKukice(List<RasterRegion> regions)
        {
            // spojiti regione na takav nacin da 
            // tacke iznad slova (npr. u  i,j)
            // i kukice iznad slova (npr. u š,č,ć,ž)
            // ne budu zasebni regioni, već da pripadaju celom slovu
            return regions;
        }

        private string Prepoznaj(Bitmap bmp)
        {
            string prepoznato = "";

            return prepoznato;
        }

        private void btnRecognizeAll_Click(object sender, EventArgs e)
        {
            ClearImageEditor();
            Bitmap bmp = imageEditorDisplay1.mapa.bmp;
            string prepoznato = Prepoznaj(bmp);

            tbText.Text = prepoznato;
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            ClearImageEditor();
        }

        private void ClearImageEditor()
        {
            imageEditorDisplay1.mapa.poligoni.Clear();
            imageEditorDisplay1.mapa.tacke.Clear();
            imageEditorDisplay1.mapa.linije.Clear();
            imageEditorDisplay1.mapa.labele.Clear();
            imageEditorDisplay1.selectedIndexer.clear();
            imageEditorDisplay1.Refresh();
        }

        private void btnSlikaZaObucavanje_Click(object sender, EventArgs e)
        {
            Bitmap bmp = kolokvijum.SlikaZaObucavanje();
            string obucavajuciSkup = kolokvijum.Alfabet;
            tbTrenningSet.Text = obucavajuciSkup + Environment.NewLine + obucavajuciSkup + Environment.NewLine + obucavajuciSkup;
            imageEditorDisplay1.selectedIndexer.clear();
            imageEditorDisplay1.mapa.bmp = bmp;
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
        }

        private void btnSlikaZaTestiranje_Click(object sender, EventArgs e)
        {
            if (kolokvijum != null)
            {
                imageEditorDisplay1.selectedIndexer.clear();
                Bitmap bmp = kolokvijum.SlikaZaTest();
                imageEditorDisplay1.mapa.bmp = bmp;
                imageEditorDisplay1.FitImage();
                imageEditorDisplay1.Refresh();
            }
        }

        private void btnProvera_Click(object sender, EventArgs e)
        {
            if (kolokvijum != null)
            {
                kolokvijum.Provera(tbText.Text);
            }
        }

        private void btnOcenjivanje_Click(object sender, EventArgs e)
        {
            if(softPipe==null) {
                btnObuci_Click(null,null);
            }
            if (kolokvijum != null)
            {
                int n = 20;
                for (int i = 0; i < n; i++)
                {
                    
                    Bitmap bmp = kolokvijum.SlikaZaTest();
                    string prepoznato = softPipe.execute(bmp);
                    kolokvijum.Provera(prepoznato);
                }
                ClearImageEditor();
            }
        }

        private void btnTest_Click(object sender, EventArgs e) {
            /*
            string wp="[a-zA-ZŠĐŽĆČšđčćž]+";
            string fp="..\\..\\..\\CrtaniHobbit.txt";
            string word="sta";
            CDictionary dict=new CDictionary(fp,wp);
            dict.addSmallPricePair('s', 'š');
            lblTest.Text=dict.findNearesWord(word);

            Bitmap bmp = imageEditorDisplay1.mapa.bmp;
            CCTBkmeans km = new CCTBkmeans(Rectangle.Empty);

            imageEditorDisplay1.mapa.bmp = ImageUtil.matrixToBitmap(km.transform(bmp));
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
            */
        }

        private void btnCreateLib_Click(object sender, EventArgs e) {
            if(imageEditorDisplay1.mapa.bmp==null) {
                imageEditorDisplay1.mapa.bmp=kolokvijum.SlikaZaObucavanje();
            }
            softPipe=new CSoftLib();

            CCTcolorInverse colorInverse=new CCTcolorInverse();
            //softPipe.addColorTransformation(colorInverse);
            
            Rectangle rectangle;
            if(imageEditorDisplay1.mapa.poligoni.Count==0){
                rectangle=Rectangle.Empty;            
            }else{
                Poligon bb=imageEditorDisplay1.mapa.poligoni[0].getBoundingBox();
                int xMin=(int)bb.tacke[0].x;
                int xMax=(int)bb.tacke[1].x;

                int yMin=(int)bb.tacke[0].y;
                int yMax=(int)bb.tacke[2].y;
                rectangle=new Rectangle(xMin, yMin, xMax, yMax);
            }
            CCTBkmeans kmeansColor=new CCTBkmeans(rectangle,imageEditorDisplay1.mapa.bmp);
            softPipe.setColorToBinary(kmeansColor);

            CBTerosion erosion=new CBTerosion();
            CBTdilation dilatation=new CBTdilation();
            CBTlineElimination lineTerminator=new CBTlineElimination(2);
            CBTborderElimination borderTerminator=new CBTborderElimination(3);
            softPipe.addBinaryTransformation(erosion);
            softPipe.addBinaryTransformation(dilatation);
            //softPipe.addBinaryTransformation(lineTerminator);
            softPipe.addBinaryTransformation(borderTerminator);

            CRLregionLabelling regionLabelling=new CRLregionLabelling(Convert.ToInt32(numericRedoviPrepozavanje.Value),
                Convert.ToInt32(numericRedoviObucavanje.Value));
            softPipe.setRegionLabelling(regionLabelling);

            int dimenzijaUlaza=64;
            //velicina srednjih slojeva mreze
            int[] dus=new int[] { 40 };
            CNNbackPropagation nn=new CNNbackPropagation(dimenzijaUlaza, dus);
            softPipe.setNeuralNetwork(nn);

            /*
            string trainingRow=CNNbackPropagation.findAlphabet(
                "..\\..\\..\\alfabet.txt", ",");
            */
            CLevenstein levenstein=new CLevenstein("..\\..\\..\\CrtaniHobbit.txt","[a-zčćžšđ]+");
            levenstein.setChangedCharacted('u', 'ự');
            softPipe.setDictonaryCheck(levenstein);
        }

        private void btnObuci_Click(object sender, EventArgs e) {
            if(softPipe==null)
                btnCreateLib_Click(null, null);
            List<string> learningRows=new List<string>();
            string trainingRow=CNNbackPropagation.findAlphabet(
                "..\\..\\..\\alfabet.txt", ",");
            learningRows.Add(trainingRow);
            learningRows.Add(trainingRow);
            learningRows.Add(trainingRow);
            softPipe.train(kolokvijum.SlikaZaObucavanje(), learningRows);

            //prikazi gresku obucavanja
            Function f1=new Function(Color.Red, softPipe.neuralNetwork.getErrors(), Function.VBAR);
            List<Function> ff=new List<Function>();
            ff.Add(f1);
            FrmChart chart=new FrmChart(ff);
            chart.Show();
        }

        private void btnColorTransformation_Click(object sender, EventArgs e) {
            Bitmap image=imageEditorDisplay1.mapa.bmp;
            if(softPipe==null)
                btnCreateLib_Click(null,null);
            softPipe.executeColorTransformation(image);
            showImage(softPipe.firstStageResult);
        }

        private void btnColorToBinary_Click(object sender, EventArgs e) {
            Bitmap image=imageEditorDisplay1.mapa.bmp;
            if(softPipe==null)
                btnCreateLib_Click(null, null);
            softPipe.executeColorToBinary(image);
            showImage(CImageUtil.matrixToBitmap(softPipe.secondStageResult));
        }

        private void btnBinaryTransformation_Click(object sender, EventArgs e) {
            Bitmap image=imageEditorDisplay1.mapa.bmp;
            if(softPipe==null)
                btnCreateLib_Click(null, null);
            softPipe.executeBinaryTransformation(CImageUtil.bitmapToByteMatrix(image));
            showImage(CImageUtil.matrixToBitmap(softPipe.thirdStageResult));
        }

        private void btnRegionLabelling_Click(object sender, EventArgs e) {
            Bitmap image=imageEditorDisplay1.mapa.bmp;
            if(softPipe==null)
                btnCreateLib_Click(null, null);
            softPipe.executeRegionLabelling(CImageUtil.bitmapToByteMatrix(image),true);
            showRegions();
            int numberOfRegions;
            lblTest.Text="";
            foreach(List<CRasterRegion> row in softPipe.fourthStageResult){
                numberOfRegions=0;
                foreach(CRasterRegion region in row) {
                    numberOfRegions++;
                }
                lblTest.Text+=numberOfRegions+"\n";
            }
            
        }

        private void btnNeuralNetwork_Click(object sender, EventArgs e) {
            if(kolokvijum!=null) {
                Bitmap bmp=kolokvijum.SlikaZaTest();
                imageEditorDisplay1.mapa.bmp=bmp;
                imageEditorDisplay1.FitImage();
                imageEditorDisplay1.Refresh();
                tbNeuralNetwork.Text=softPipe.execute(bmp);
                showImage(CImageUtil.matrixToBitmap(softPipe.thirdStageResult));
                showRegions();
            }
        }

        public void showImage(Bitmap bmp) {
            imageEditorDisplay1.mapa.bmp=bmp;
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
        }

        public static void printMatrix(byte[,] matrix) {
            StreamWriter writer=new StreamWriter("log.txt");
            for(int i=0;i<matrix.GetLength(0);i++) {
                for(int j=0;j<matrix.GetLength(1);j++) {
                    writer.Write(matrix[i, j].ToString()+" ");
                }
                writer.WriteLine();
            }
            writer.Flush();
            writer.Close();
        }

        public static void printLog(string s) {
            StreamWriter writer = new StreamWriter("log.txt");
            writer.Write(s);
            writer.Flush();
            writer.Close();
        }

        public void showRegions() {
            List<List<CRasterRegion>> regions=
                new List<List<CRasterRegion>>(softPipe.fourthStageResult);
            //izbacivanje praznih mesta
            for(int i=0;i<regions.Count;i++) {
                for(int j=0;j<regions[i].Count;j++) {
                    if(regions[i][j].Equals(CRasterRegion.spaceRegion)) {
                        regions[i].RemoveAt(j);
                        j=j>0?j-1:j;
                    }
                }
            }

            int regId=0;
            int redBr=0;
            imageEditorDisplay1.selectedIndexer.clear();
            foreach(List<CRasterRegion> row in regions) {
                foreach(CRasterRegion reg in row) {
                    List<Tacka> tacke=new List<Tacka>();
                    tacke.Add(new Tacka(reg.minX-1, reg.minY-1));
                    tacke.Add(new Tacka(reg.maxX+1, reg.minY-1));
                    tacke.Add(new Tacka(reg.maxX+1, reg.maxY+1));
                    tacke.Add(new Tacka(reg.minX-1, reg.maxY+1));
                    Poligon rec=new Poligon(tacke, Color.FromArgb(10, Color.Green));
                    imageEditorDisplay1.selectedIndexer.add(rec);
                    reg.Tag="";
                    if(!alfabet.ContainsKey(reg.Tag)) {
                        alfabet.Add(reg.Tag, redBr);
                        alfabetInv.Add(redBr, reg.Tag);
                        redBr++;
                    }

                    Labela lbl=new Labela(reg.minX-1, reg.minY-1);
                    lbl.boja=Color.Red;
                    lbl.labela=reg.Tag;
                    imageEditorDisplay1.selectedIndexer.add(lbl);
                    regId++;
                }
            }
            imageEditorDisplay1.FitImage();
            imageEditorDisplay1.Refresh();
        }
    }
}
